package com.forsir.android.mhfinance;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;

import com.forsir.android.mhfinance.helper.CalculatorSolver;

public class CalculatorDialog extends Activity {
	public final static String RETURN_CALCULATOR_RESULT = "calculator_result";
	public final static String REQUEST_EXPRESSION = "expression";
	private final static String SAVE_EXPRESSION = "expression";

	String currencyBefore = "";
	String currencyAfter = "";
	String returnText = "";

	EditText expressionText;
	Button saveButton;
	Button cancelButton;
	ImageButton deleteButton;
	Button bracketButton;
	Button delimiterButton;

	int[] buttons;
	private SharedPreferences mPreferenceSettings;
	boolean solvingByPrecedence;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		buttons = new int[] { R.id.calculator_number_0, R.id.calculator_number_1, R.id.calculator_number_2, R.id.calculator_number_3, R.id.calculator_number_4,
		        R.id.calculator_number_5, R.id.calculator_number_6, R.id.calculator_number_7, R.id.calculator_number_8, R.id.calculator_number_9,
		        R.id.calculator_number_delimiter, R.id.calculator_number_divide, R.id.calculator_number_minus, R.id.calculator_number_multiply,
		        R.id.calculator_number_multiply, R.id.calculator_number_plus, R.id.calculator_number_bracket };

		setContentView(R.layout.calculator);
		mPreferenceSettings = PreferenceManager.getDefaultSharedPreferences(this);
		solvingByPrecedence = mPreferenceSettings.getBoolean(getString(R.string.key_solving_by_precedence), true);

		currencyBefore = mPreferenceSettings.getString(getString(R.string.key_currency_before), getString(R.string.currency_before));
		currencyAfter = " " + mPreferenceSettings.getString(getString(R.string.key_currency_after), getString(R.string.currency_after));

		saveButton = (Button) findViewById(R.id.calculator_save);
		cancelButton = (Button) findViewById(R.id.calculator_cancel);
		deleteButton = (ImageButton) findViewById(R.id.calculator_backspace);
		bracketButton = (Button) findViewById(R.id.calculator_number_bracket);
		expressionText = (EditText) findViewById(R.id.calculator_amount_input);
		delimiterButton = (Button) findViewById(R.id.calculator_number_delimiter);

		if (delimiterButton != null) {
			delimiterButton.setText(String.format("%.1f", 0.0).replace("0", ""));
		}

		saveButton.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				final Intent data = new Intent();
				data.putExtra(RETURN_CALCULATOR_RESULT, returnText);

				CalculatorDialog.this.setResult(Activity.RESULT_OK, data);
				// Close this Activity
				CalculatorDialog.this.finish();
			}
		});

		cancelButton.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				// Close this Activity
				CalculatorDialog.this.finish();
			}
		});

		Button numberButton;
		final int buttonCount = buttons.length;
		for (int i = 0; i < buttonCount; i++) {
			numberButton = (Button) findViewById(buttons[i]);
			if (numberButton != null) {
				numberButton.setOnClickListener(numberButtonOnClickListener);
			}
		}
		switchNumbers();

		expressionText.setOnKeyListener(expressionTextKeyListener);
		deleteButton.setOnClickListener(deleteButtonOnClickListener);
		deleteButton.setOnLongClickListener(deleteButtonOnLongClickListener);

		if (savedInstanceState != null) {
			// return from activity inactivity
			expressionText.setText(savedInstanceState.getString(SAVE_EXPRESSION));
		} else {
			final Bundle extras = getIntent().getExtras();
			if (extras != null) {
				// get parameter calling application
				expressionText.setText(extras.getString(CalculatorDialog.REQUEST_EXPRESSION));
			} else {
				// get last expression
				expressionText.setText(CalculatorSolver.lastExpression);
			}
		}

		textChanged();
	}

	private void switchNumbers() {
		if (mPreferenceSettings.getBoolean(getString(R.string.key_buttons_as_phone), true)) {
			return;
		}

		Button numberButton;
		final int buttonCount = buttons.length;
		for (int i = 0; i < buttonCount; i++) {
			numberButton = (Button) findViewById(buttons[i]);
			if (numberButton != null) {

				switch (numberButton.getText().charAt(0)) {
					case '1':
						numberButton.setText("7");
						break;
					case '2':
						numberButton.setText("8");
						break;
					case '3':
						numberButton.setText("9");
						break;
					case '7':
						numberButton.setText("1");
						break;
					case '8':
						numberButton.setText("2");
						break;
					case '9':
						numberButton.setText("3");
						break;
				}
			}
		}
	}

	OnKeyListener expressionTextKeyListener = new OnKeyListener() {
		public boolean onKey(View v, int keyCode, KeyEvent event) {
			if (event.getAction() == KeyEvent.ACTION_UP) {
				textChanged();
			}
			return false;
		}
	};

	OnClickListener numberButtonOnClickListener = new OnClickListener() {
		public void onClick(View v) {
			int keyCode = 0;
			final String buttonText = ((Button) v).getText().toString();
			if (buttonText.contentEquals("0")) {
				keyCode = KeyEvent.KEYCODE_0;
			}
			if (buttonText.contentEquals("1")) {
				keyCode = KeyEvent.KEYCODE_1;
			}
			if (buttonText.contentEquals("2")) {
				keyCode = KeyEvent.KEYCODE_2;
			}
			if (buttonText.contentEquals("3")) {
				keyCode = KeyEvent.KEYCODE_3;
			}
			if (buttonText.contentEquals("4")) {
				keyCode = KeyEvent.KEYCODE_4;
			}
			if (buttonText.contentEquals("5")) {
				keyCode = KeyEvent.KEYCODE_5;
			}
			if (buttonText.contentEquals("6")) {
				keyCode = KeyEvent.KEYCODE_6;
			}
			if (buttonText.contentEquals("7")) {
				keyCode = KeyEvent.KEYCODE_7;
			}
			if (buttonText.contentEquals("8")) {
				keyCode = KeyEvent.KEYCODE_8;
			}
			if (buttonText.contentEquals("9")) {
				keyCode = KeyEvent.KEYCODE_9;
			}
			if (buttonText.contentEquals("+")) {
				keyCode = KeyEvent.KEYCODE_PLUS;
			}
			if (buttonText.contentEquals("-")) {
				keyCode = KeyEvent.KEYCODE_MINUS;
			}
			if (buttonText.contentEquals("/")) {
				keyCode = KeyEvent.KEYCODE_SLASH;
			}
			if (buttonText.contentEquals("*")) {
				keyCode = KeyEvent.KEYCODE_STAR;
			}
			if (buttonText.contentEquals("(")) {
				// keyCode = KeyEvent.KEYCODE_LEFT_BRACKET;
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ALT_LEFT));
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_9));
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_9));
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ALT_LEFT));
			}
			if (buttonText.contentEquals(")")) {
				// keyCode = KeyEvent.KEYCODE_RIGHT_BRACKET;
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ALT_LEFT));
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0));
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0));
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ALT_LEFT));
			}
			if (buttonText.contentEquals(".")) {
				keyCode = KeyEvent.KEYCODE_PERIOD;
			}

			if (buttonText.contentEquals(",")) {
				keyCode = KeyEvent.KEYCODE_COMMA;
			}

			if (keyCode != 0) {
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
				expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
			}
		}
	};

	private void textChanged() {
		// Executes when text is changed
		// compute string and set result
		final String text = expressionText.getText().toString();
		CalculatorSolver.lastExpression = text;
		setBracket(text);

		if (text.length() > 0) {
			try {
				returnText = CalculatorSolver.solve(text + "+", solvingByPrecedence);
				this.setTitle(currencyBefore + returnText + currencyAfter);
			} catch (final Exception e2) {
				returnText = "";
				this.setTitle(R.string.cannot_compute);
			}
		} else {
			returnText = "";
			this.setTitle(R.string.calculator);
		}
	}

	private void setBracket(String text) {
		if (bracketButton == null) {
			return;
		}

		int count = 0;
		final int length = text.length();
		char ch;
		for (int i = 0; i < length; i++) {
			ch = text.charAt(i);
			if (ch == ')') {
				count--;
			}
			if (ch == '(') {
				count++;
			}
		}
		if (count > 0) {
			bracketButton.setText(")");
		} else {
			bracketButton.setText("(");
		}
	}

	OnClickListener deleteButtonOnClickListener = new OnClickListener() {
		public void onClick(View v) {
			expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
			expressionText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
		}
	};

	OnLongClickListener deleteButtonOnLongClickListener = new OnLongClickListener() {
		public boolean onLongClick(View v) {
			expressionText.setText("");
			textChanged();
			return false;
		}
	};

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putString(SAVE_EXPRESSION, expressionText.getText().toString());
	}
}
